﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Echegoyen.Models;
using WebMatrix.WebData;

namespace Echegoyen.Controllers
{
    [Authorize(Roles = "Admins")]
    public class PrestamoController : Controller
    {
        private IContext db;
        private IMyLogger log;

        public PrestamoController(IContext db, IMyLogger log)
        {
            this.db = db;
            this.log = log;
        }

        //
        // GET: /Prestamo/

        public ActionResult Index()
        {
            // Al listar anulo las reservas asignadas demasiado viejas.
            List<Prestamo> rs = db.Prestamo.Where(x => x.Estado == "Asignado").ToList();
           
            foreach(Prestamo reservaAsignada in rs) {
                if (reservaAsignada.Fecha < DateTime.Now.AddDays(-3))
                {
                    reservaAsignada.Anular();
                }
            }
            db.SaveChanges();

            return View(db.Prestamo.OrderByDescending(x => x.Fecha).ToList());
        }


        // GET
        public ActionResult Despachar(int id = 0)
        {
            Usuario u = db.Prestamo.First(x => x.PrestamoId == id).Usuario;     

            int cuantos = db.Prestamo.Where(x => x.Estado == "Despachado" && x.Usuario.UsuarioId == u.UsuarioId).ToList().Count;
            if (cuantos > 2)
            {
                TempData["msg"] = "El usuario ya tiene el máximo de préstamos despachados (3).";
                return RedirectToAction("Index");
            }

            ViewBag.opcionesDias = new SelectList(new[]
                                          {
                                                  new{ID="1",Name="1"},
                                                  new{ID="2",Name="2"},                                       
                                                  new{ID="3",Name="3"},   
                                                  new{ID="5",Name="5"},   
                                                  new{ID="10",Name="10"},   
                                                  new{ID="15",Name="15"},   
                                                  new{ID="20",Name="20"},   
                                                  new{ID="30",Name="30"},   
                                          },
                "ID", "Name", "30");

            Prestamo p = db.Prestamo.Find(id);
            if (p == null)
            {
                log.Error("PrestamoController", "No se puede despachar un préstamo inexistente: " + id, null);
                return RedirectToAction("Index");
            }

            if (!p.Estado.Equals("Asignado"))
            {
                TempData["msg"] = "El ejemplar debe estar asignado para poder ser despachado.";
                return RedirectToAction("Index");
            }

            return View(p);
        }

        // POST
        [HttpPost, ActionName("Despachar")]
        [ValidateAntiForgeryToken]
        public ActionResult DespacharConfirmed(int id = 0, int CantDias = -1)
        {
            Prestamo p = db.Prestamo.Find(id);
            if (p == null)
            {
                log.Error("PrestamoController", "No se puede despachar un préstamo inexistente: " + id, null);
                return RedirectToAction("Index");
            }

            p.CantDias = CantDias;
            db.SaveChanges();
            p.Despachar();
            db.SaveChanges();

            return RedirectToAction("Index");
        }


        // GET
        public ActionResult Devolver(int id = 0)
        {
            Prestamo p = db.Prestamo.Find(id);
            if (p == null)
            {
                log.Error("PrestamoController", "No se puede devolver un préstamo inexistente: " + id, null);  
                return RedirectToAction("Index");
            }

            if (!p.Estado.Equals("Despachado"))
            {
                TempData["msg"] = "El ejemplar debe haber sido despachado para poder ser devuelto.";
                return RedirectToAction("Index");
            }

            return View(p);
        }

        // POST
        [HttpPost, ActionName("Devolver")]
        [ValidateAntiForgeryToken]
        public ActionResult DevolverConfirmed(int id = 0)
        {
            Prestamo p = db.Prestamo.Find(id);
            if (p == null)
            {
                log.Error("PrestamoController", "No se puede devolver un préstamo inexistente: " + id, null);
                return RedirectToAction("Index");
            }

            p.Devolver();
            db.SaveChanges();
            p.Ejemplar.Material.AsignarUno();

            return RedirectToAction("Index");
        }




        //
        // GET: /Prestamo/Details/5

        public ActionResult Details(int id = 0)
        {
            Prestamo prestamo = db.Prestamo.Find(id);
            if (prestamo == null)
            {
                log.Error("PrestamoController", "No se pueden dar los detalles de un préstamo inexistente: " + id, null);         
                return HttpNotFound();
            }
            return View(prestamo);
        }

        //
        // GET: /Prestamo/Create

        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Prestamo/Create

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Prestamo prestamo)
        {
            if (ModelState.IsValid)
            {
                db.Prestamo.Add(prestamo);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            
            log.Error("PrestamoController", "El préstamo que se pretendía crear no es válido.", null);        
            return View(prestamo);
        }

        //
        // GET: /Prestamo/Edit/5

        public ActionResult Edit(int id = 0)
        {
            Prestamo prestamo = db.Prestamo.Find(id);
            if (prestamo == null)
            {
                log.Error("PrestamoController", "No se puede editar un préstamo inexistente: " + id, null);
                return HttpNotFound();
            }
            return View(prestamo);
        }

        //
        // POST: /Prestamo/Edit/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Prestamo prestamo)
        {
            if (ModelState.IsValid)
            {
                db.SetModified(prestamo);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            log.Error("PrestamoController", "El préstamo que se pretendía editar no es válido.", null);
            return View(prestamo);
        }

        //
        // GET: /Prestamo/Delete/5

        public ActionResult Delete(int id = 0)
        {
            Prestamo prestamo = db.Prestamo.Find(id);
            if (prestamo == null)
            {
                log.Error("PrestamoController", "No se puede eliminar un préstamo inexistente: " + id, null);
                return HttpNotFound();
            }
            return View(prestamo);
        }

        //
        // POST: /Prestamo/Delete/5

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Prestamo prestamo = db.Prestamo.Find(id);
            if (prestamo == null)
            {
                log.Error("PrestamoController", "No se puede eliminar un préstamo inexistente: " + id, null);      
                return RedirectToAction("Index");
            }

            db.Prestamo.Remove(prestamo);
            db.SaveChanges();

            prestamo.Ejemplar.Material.AsignarUno();

            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}